Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove 0-size and variable size array members #13945

Merged
merged 1 commit into from
Nov 14, 2015
Merged

Remove 0-size and variable size array members #13945

merged 1 commit into from
Nov 14, 2015

Conversation

yuyichao
Copy link
Contributor

For some reason, the llvm-config from LLVM 3.7 adds -pedantic to cflags and cxxflags. This causes a huge amount of compiler warnings (mainly because of JL_DATA_TYPE). I couldn't find out why did LLVM starts doing this or how to workaround it in general so I decided to fix most of the warnings....

This PR doesn't completely fix all the -Wpedantic warnings (the ones that are not fixed is anonymous structs which we use for bitsfields in a union. This turns out to be valid C11 but not valid C++ yet...).

This could break embedding. In particular,

  1. jl_value_t is only a declaration now. Direct use of jl_value_t instead of jl_value_t* shouldn't be necessary.
  2. Types with variable array members do no have such member anymore. The address of the variable length array is calculated directly with pointer arithmetics instead. Notes about how each of them should be updated,
    1. jl_value_t::fieldptr

      We already have jl_data_ptr and this macro should be used instead.

    2. jl_sym_t::data

      Use jl_symbol_name, which is also the name of the exported function.

    3. jl_taggedvalue_t::value

      (not actually a flexible array member but was serving a similar purpose). I doubt any embedding code manipulate jl_taggedvalue_t directly but jl_valueof is provided as a convenient way to access the value pointer.

    4. jl_svec_t::data

      We already have jl_svec_data and this macro should be used instead.

    5. jl_datatype_t::fields

      This shouldn't be accessed directly since Variable size field descriptors #13147. jl_datatype_fields macro is also added to get the address of the fields in the rare case it is needed.

  3. If any code was relying on JL_DATA_TYPE in a non-gc allocated struct to provide necessary alignment, it needs to find another way to do it. (define its own zero length array member, use the alignment attributes etc.)
  4. The presence of jl_valueof macro and function could be used as a compile time and runtime check to detect this change.

@vtjnash Ref #13787
@tkelman This should make the code more MSVC compatible but it's also possible that I break something without realizing it....

@tkelman
Copy link
Contributor

tkelman commented Nov 11, 2015

built fine on msvc straight away, nicely done.

struct {
int64_t isref;
Function *f;
} data[];
} data[1];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure this change isn't ISO-conforming C. The old version should have been more correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is not ISO-conforming about this?

The warning I get is

yuyichao% LANG=C g++ -pedantic -x c++ -Wall -Wextra - -c -o /dev/null <<EOF
typedef struct {
        int a;
        int b[];
} A;
EOF
<stdin>:3:8: warning: ISO C++ forbids zero-size array 'b' [-Wpedantic]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK so I find this stackoverflow thread. And it seems that there basically isn't a ISO C++ conforming way to do this.

  • The flexible member is invalid C++ syntax and causes warning under -pedantic.
  • The single element array could technically be UB but It's not clear if it's legal or portable, but it is rather popular. and does seem to work under all known implementations.... (and also issue no warnings.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does seem to work under all known implementations

http://stackoverflow.com/a/10500898

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps we should just switch this struct to a std::unordered_map< uint64_t, Function* >

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing the [1] thing can now give you runtime errors on OS X, cf #13845

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps we should just switch this struct to a std::unordered_map< uint64_t, Function* >

We don't require c++11 in general yet but it could be std::map? Looks like it currently is simply a std::vector?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::vector< std::pair< int64_t, Function* > > would also work. it's expected to be a very small set, so actually it's best not to use unordered_map, which may significantly over-allocate.

@yuyichao
Copy link
Contributor Author

I updated the PR to not use [1] and calculate the addresses directly instead. I've implemented most of what @vtjnash suggested except,

  1. Use std::vector or std::map for cFunctionList. It's requires slightly more changes to implement and introduce one more indirection since we can only store a pointer in the C structure.
  2. Define jl_value_t as a union. It's largely independent of this PR.

The static inline version of jl_symbol_name_ is to provide better type check. jl_sym_t::name is used a lot in the code and usually in the form of ...->name->name (sometimes ...->name->name->name) and is really likely to get wrong if there's not a strong type check.

@vtjnash
Copy link
Member

vtjnash commented Nov 11, 2015

lgtm

@tkelman
Copy link
Contributor

tkelman commented Nov 11, 2015

6db03d0 looks like it also works on msvc. Do any of the embedding docs or examples need updating for this?

@yuyichao
Copy link
Contributor Author

Do any of the embedding docs or examples need updating for this?

Good question. All the changes are API level details (i.e. shouldn't break ABI) and it seems that none of these are covered by the embedding doc. (We don't have doc for the various jl_*_t types).

@yuyichao
Copy link
Contributor Author

Rebased to resolve conflict with #13787 .... I guess I shouldn't have silently included the fix for the variable not used warning when assert is off....

@vtjnash
Copy link
Member

vtjnash commented Nov 11, 2015

Oops, i guess at least one of us shouldn't have silently added that fix. We very nearly came up with the same patch too :/

@yuyichao
Copy link
Contributor Author

Rebased and add a short comment about jl_symbol_name_. Will merge tomorrow if there's no other issues.

yuyichao added a commit that referenced this pull request Nov 14, 2015
Remove 0-size and variable size array members
@yuyichao yuyichao merged commit 9c9a180 into master Nov 14, 2015
@yuyichao yuyichao deleted the yyc/gcc-warn branch November 14, 2015 12:53
yuyichao added a commit that referenced this pull request Jan 28, 2016
This flag is added by llvm-config 3.7 on ArchLinux.

Ref #13945
yuyichao added a commit that referenced this pull request Jan 28, 2016
This flag is added by llvm-config 3.7 on ArchLinux.

Ref #13945
yuyichao added a commit that referenced this pull request Jan 28, 2016
This flag is added by llvm-config 3.7 on ArchLinux.

Ref #13945
yuyichao added a commit that referenced this pull request Jan 28, 2016
This flag is added by llvm-config 3.7 on ArchLinux.

Ref #13945
yuyichao added a commit that referenced this pull request Jan 28, 2016
This flag is added by llvm-config 3.7 on ArchLinux.

Ref #13945
yuyichao added a commit that referenced this pull request Jan 28, 2016
This flag is added by llvm-config 3.7 on ArchLinux.

Ref #13945
yuyichao added a commit that referenced this pull request Jan 29, 2016
This flag is added by llvm-config 3.7 on ArchLinux.

Ref #13945
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants